﻿using System;
using System.Collections.Specialized;
using System.IO;

using WebDavProcessor.Constants;
using WebDavProcessor.Interfaces;
using WebDavProcessor.Resources;

namespace WebDavProcessor.Methods
{
    public class WebDavGet : WebDavMethod
    {
        public WebDavGet(IWebDavRequest webDavRequest)
            : base(webDavRequest)
        {
        }
        public WebDavGet(string requestMethod, Uri requestUri, NameValueCollection requestHeaders, Stream requestInputStream)
            : base(requestMethod, requestUri, requestHeaders, requestInputStream)
        {
        }

        public override void ProcessRequest(IWebDavResponse webDavResponse, IWebDavResourceProvider resourceProvider)
        {
            WebDavResource resource;
            if (!(resourceProvider is IWebDavIOProvider))
            {
                WebDavMethod.SetError(webDavResponse, WebDavStatusCodes.NotImplemented);
                return;
            }
            try
            {
                resource = (resourceProvider as IWebDavIOProvider).Read(this.RequestUri.ToString());
                if (resource == null)
                {
                    WebDavMethod.SetError(webDavResponse, WebDavStatusCodes.NotImplemented);
                    return;
                }
                if (!(resource is WebDavStreamResource))
                {
                    WebDavMethod.SetError(webDavResponse, resource.Status);
                    return;
                }

                WebDavStreamResource streamResource = resource as WebDavStreamResource;
                if (streamResource.Data == null)
                {
                    WebDavMethod.SetError(webDavResponse, WebDavStatusCodes.NotFound);
                    return;
                }
                webDavResponse.StatusCode = WebDavStatusCodes.OK;
                webDavResponse.StatusDescription = WebDavStatusDescriptions.OK;
                webDavResponse.OutputStream = streamResource.Data;
                webDavResponse.Headers[WebDavHeaders.ContentLength] = streamResource.Data.Length.ToString();

                object property;
                property = streamResource.GetContentLanguage;
                if (property != null)
                {
                    webDavResponse.Headers[WebDavHeaders.ContentLanguage] = property.ToString();
                }
                property = streamResource.GetContentType;
                if (property != null)
                {
                    webDavResponse.Headers[WebDavHeaders.ContentType] = property.ToString();
                }
                property = streamResource.GetETag;
                if (property != null)
                {
                    webDavResponse.Headers[WebDavHeaders.ETag] = property.ToString();
                }
                property = streamResource.GetLastModified;
                if (property != null)
                {
                    webDavResponse.Headers[WebDavHeaders.LastModified] = property.ToString();
                }
            }
            catch (WebDavException e)
            {
                WebDavMethod.SetError(webDavResponse, e.StatusCode);
                return;
            }
            catch (Exception)
            {
                WebDavMethod.SetError(webDavResponse, WebDavStatusCodes.InternalServerError);
                return;
            }
        }
    }
}
